package org.rainbowinverted.charging.device.connect.bl.server.handler;

import cn.hutool.core.util.HexUtil;
import com.dix.codec.bkv.BKV;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.rainbowinverted.charging.device.connect.bl.server.message.in.BlDeviceEventInfoIn;
import org.rainbowinverted.charging.device.connect.bl.server.message.in.BlDeviceEventReportIn;
import org.rainbowinverted.charging.device.connect.bl.server.message.out.BlDeviceEventReportOut;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author huaiping
 */
@Slf4j
@Component
@AllArgsConstructor
@ChannelHandler.Sharable
public class BlDeviceEventReportHandler extends BlAbstractHandler<BlDeviceEventReportIn, BlDeviceEventReportOut> {

    @Override
    public void write(BlDeviceEventReportOut message, BKV bkv) {
        addAck(bkv, message.getAck());
    }

    @Override
    public void read(ChannelHandlerContext channelHandlerContext, BKV bkv) {
        Long deviceNo = getDeviceNo(bkv);
        Long serialNo = getSerialNo(bkv);
        Integer gunNo = getGunNo(bkv);
        LocalDateTime time = getTime(bkv);
        // 事件编码
        /*
            1001-插枪事件
            1002-拔枪事件
            1011-开门事件
            1012-关门事件
            2001-过压发生
            2002-过压恢复
            2011-欠压发生
            2012-欠压恢复
            3001-急停按钮触发
            3002-急停按钮恢复
            3011-继电器过温发生
            3012-继电器过温恢复
            3021-过载过流发生
            3022-过载过流恢复
            3031-计量通讯异常
            3032-计量通讯恢复
            3041-继电器粘连
            3042-继电器粘连恢复
            3051-继电器粘连
            3052-继电器粘连恢复
            3061-设备积水
            3062-设备积水恢复
            3071-AC电源断开
            3072-AC电源恢复
         */
        short eventCode = Short.parseShort(HexUtil.encodeHexStr(bkv.get(0x5a).getValue()), 16);
        BlDeviceEventInfoIn eventInfo = BlDeviceEventInfoIn.builder()
                .gunInserted(eventCode == 0x1001)
                .gunPullOfOut(eventCode == 0x1002)
                .overVoltage(eventCode == 0x2001)
                .overVoltageRecover(eventCode == 0x2002)
                .underVoltage(eventCode == 0x2011)
                .underVoltageRecover(eventCode == 0x2012)
                .emergency(eventCode == 0x3001)
                .emergencyRecover(eventCode == 0x3002)
                .acPowerOff(eventCode == 0x3071)
                .acPowerRecover(eventCode == 0x3072).build();
        BlDeviceEventReportIn deviceEventReportDTO = BlDeviceEventReportIn.of(deviceNo, gunNo, time,
                eventInfo, LocalDateTime.now());
        // 确认消息
        channelHandlerContext.writeAndFlush(new BlDeviceEventReportOut(deviceNo, serialNo, (byte)0x01));
        log.info("device event report info: {}", deviceEventReportDTO);

    }
}
